package ms.maplestory.boot.packets.universal;

import ms.maplestory.boot.client.character.Char;
import ms.maplestory.boot.client.character.Inventory.Item;
import ms.maplestory.boot.connection.OutPacket;
import ms.maplestory.boot.enums.stage.CharDataFlag;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class CharacterData {

    public static void encode(OutPacket out, Char chr, CharDataFlag mask) {
        out.encodeLong(mask.get());
        out.encodeByte(0); // CombatOrders
        out.encodeByte(0);
        if (mask.isInMask(CharDataFlag.Character)) {
            CharacterStat.encode(out, chr.getStat());
            out.encodeByte(0); // FriendMax
            boolean bool = false;
            out.encodeByte(bool);
            if (bool) {
                out.encodeString("");
            }
        }
        if (mask.isInMask(CharDataFlag.Money)) {
            out.encodeInt(chr.getStat().getMoney());
        }
        if (mask.isInMask(CharDataFlag.InventorySize)) {
            out.encodeByte(chr.getEquipInventory().getSlots());
            out.encodeByte(chr.getUseInventory().getSlots());
            out.encodeByte(chr.getSetupInventory().getSlots());
            out.encodeByte(chr.getEtcInventory().getSlots());
            out.encodeByte(chr.getCashInventory().getSlots());
        }
        if (mask.isInMask(CharDataFlag.EquipExtExpire)) {
            out.encodeInt(0); // LowDateTime
            out.encodeInt(0); // HighDateTime
        }
        if (mask.isInMask(CharDataFlag.ItemSlotEquip)) {
            List<Item> equippedItems = new ArrayList<>(chr.getEquippedInventory().getItems());
            equippedItems.sort(Comparator.comparingInt(Item::getPosition));
            for (Item item : equippedItems) {
                int pos = item.getPosition();
                if (pos < 0 && pos > -100) {
                    out.encodeShort(Math.abs(pos));
                    ItemSlotBase.encode(out, item);
                }
            }
            out.encodeShort(0); // start of equipped nx
            for (Item item : equippedItems) {
                int pos = item.getPosition();
                if (pos <= -100 && pos > -1000) {
                    out.encodeShort(Math.abs(pos) - 100);
                    ItemSlotBase.encode(out, item);
                }
            }
            out.encodeShort(0); // start of equip inventory
            for (Item item : chr.getEquipInventory().getItems()) {
                int pos = item.getPosition();
                out.encodeShort(Math.abs(pos));
                ItemSlotBase.encode(out, item);
            }
            out.encodeShort(0); //start of evan equips
            for (Item item : equippedItems) {
                int pos = item.getPosition();
                if (pos <= -1000 && pos > -1100) {
                    out.encodeShort(Math.abs(pos));
                    ItemSlotBase.encode(out, item);
                }
            }
            out.encodeShort(0); //start of mechanic equips, ty KDMS
            for (Item item : equippedItems) {
                int pos = item.getPosition();
                if (pos <= -1100 && pos > -1200) {
                    out.encodeShort(Math.abs(pos));
                    ItemSlotBase.encode(out, item);
                }
            }
            out.encodeShort(0);
        }
        if (mask.isInMask(CharDataFlag.ItemSlotConsume)) {
            chr.getUseInventory().getItems().forEach(item -> {
                out.encodeByte(Math.abs(item.getPosition()));
                ItemSlotBase.encode(out, item);
            });
            out.encodeByte(0);
        }
        if (mask.isInMask(CharDataFlag.ItemSlotInstall)) {
            chr.getSetupInventory().getItems().forEach(item -> {
                out.encodeByte(Math.abs(item.getPosition()));
                ItemSlotBase.encode(out, item);
            });
            out.encodeByte(0);
        }
        if (mask.isInMask(CharDataFlag.ItemSlotEtc)) {
            chr.getEtcInventory().getItems().forEach(item -> {
                out.encodeByte(Math.abs(item.getPosition()));
                ItemSlotBase.encode(out, item);
            });
            out.encodeByte(0);
        }
        if (mask.isInMask(CharDataFlag.ItemSlotCash)) {
            chr.getCashInventory().getItems().forEach(item -> {
                out.encodeByte(Math.abs(item.getPosition()));
                ItemSlotBase.encode(out, item);
            });
            out.encodeByte(0);
        }
        if (mask.isInMask(CharDataFlag.SkillRecord)) {
            out.encodeShort(0);
        }
        if (mask.isInMask(CharDataFlag.SkillCoolTime)) {
            out.encodeShort(0); //size
        }
        if (mask.isInMask(CharDataFlag.QuestRecord)) {
            out.encodeShort(0); //size
        }
        if (mask.isInMask(CharDataFlag.QuestComplete)) {
            out.encodeShort(0); //size
        }
        if (mask.isInMask(CharDataFlag.MiniGameRecord)) {
            out.encodeShort(0); //size
        }
        if (mask.isInMask(CharDataFlag.RingRecord)) {
            out.encodeShort(0); //size
            out.encodeShort(0); //size
            out.encodeShort(0); //size
        }
        if (mask.isInMask(CharDataFlag.MapTransfer)) {
            for (int i = 0; i < 5; i++) { // VIP teleport map
                out.encodeInt(0);
            }
            for (int i = 0; i < 10; i++) { // VIP teleport map
                out.encodeInt(0);
            }
        }
        if (mask.isInMask(CharDataFlag.NewYearCardRecord)) {
            out.encodeShort(0); //size
        }
        if (mask.isInMask(CharDataFlag.QuestRecordEx)) {
            out.encodeShort(0); //size
        }
        if (mask.isInMask(CharDataFlag.Jaguar)) {
            if (chr.getStat().getJob() >= 3300 && chr.getStat().getJob() <= 3312) {
                out.encodeByte(0);
                for (int i = 0; i < 5; i++) {
                    out.encodeInt(0);
                }
            }
        }
        if (mask.isInMask(CharDataFlag.QuestCompleteOld)) {
            out.encodeShort(0); //size
        }
        if (mask.isInMask(CharDataFlag.ItemPot)) {
            out.encodeShort(0); //size
        }
    }

}
